package timbap.visualizer.impl.context.playlist;

import timbap.visualizer.api.exceptions.PlaylistParserException;
import timbap.visualizer.api.model.PlaylistEntry;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;

public class ExtM3UPlaylistManagerImpl extends ID3ParsingM3UPlaylistManagerImpl {
    
    public static final boolean UPDATE_PLAYLIST_FILE_BY_DEFAULT = false;
    public static final boolean ALWAYS_READ_FROM_ID3_TAGS = true;

    private static final String EXTM3U_HEADER = "#EXTM3U";
    private static final String EXTINF_HEADER = "#EXTINF:";
    private static final String EXTINF_PREFIX_REGEX = "#EXTINF:-*(\\d)+,";
    private static final String SPLIT_ARTIST_AND_SONG_REGEX = " - ";
    
    boolean playlistUpdateEnabled;
    
    public ExtM3UPlaylistManagerImpl() {
    	this(UPDATE_PLAYLIST_FILE_BY_DEFAULT);
    }

    public ExtM3UPlaylistManagerImpl(boolean pPlaylistUpdateEnabled) {
        super();
        playlistUpdateEnabled = pPlaylistUpdateEnabled;
    }


    @Override
    public List<PlaylistEntry> parsePlaylist(File pPlaylistFile)
            throws IOException, PlaylistParserException {
        
        List<PlaylistEntry> tPlaylist = new ArrayList<PlaylistEntry>();
        LineNumberReader tLineNumberReader = 
            new LineNumberReader(new FileReader(pPlaylistFile));
        
        String tCurrentLine = tLineNumberReader.readLine();
        while ((tCurrentLine.startsWith("#") && !tCurrentLine.equals(EXTM3U_HEADER)) 
        		 || (tCurrentLine.trim().length() == 0)) {
        	tCurrentLine = tLineNumberReader.readLine();
        }
        if (tCurrentLine.equals(EXTM3U_HEADER)) {
            while ((tCurrentLine = tLineNumberReader.readLine()) != null) {
                PlaylistEntry tParsedPlaylistEntry;
                if (tCurrentLine.startsWith(EXTINF_HEADER)) {
                    String tSubsequentLine = tLineNumberReader.readLine();
                    tParsedPlaylistEntry = parsePlaylistItem(
                            pPlaylistFile.getParentFile(), ALWAYS_READ_FROM_ID3_TAGS, tCurrentLine, tSubsequentLine);
                } else {
                    tParsedPlaylistEntry = super.parsePlaylistItem(
                            pPlaylistFile.getParentFile(), ALWAYS_READ_FROM_ID3_TAGS, tCurrentLine);
                }
                tPlaylist.add(tParsedPlaylistEntry);
            }
        } else {
            tPlaylist = super.parsePlaylist(pPlaylistFile);
        }
        tLineNumberReader.close();
        
        if (playlistUpdateEnabled) {
            FileWriter tFileWriter = new FileWriter(pPlaylistFile, false);
            tFileWriter.write(
                    (EXTM3U_HEADER + "\n").toCharArray());
            for (PlaylistEntry tPlaylistEntry : tPlaylist) {
                tFileWriter.write(
                        (tPlaylistEntry.toM3uExtInfString() + "\n").toCharArray());
            }
            tFileWriter.flush();
            tFileWriter.close();
        }
        
        return tPlaylist;
    }


    @Override
    protected PlaylistEntry parsePlaylistItem(File pReferenceDirectory, boolean pReadFromId3Tags, String... pLinesToParse) {

        PlaylistEntry tPlaylistEntry = null;

        if (pLinesToParse != null && pLinesToParse.length == 2) {
            
            String tExtInfMetaData = pLinesToParse[0];
            String tAudioFilePath = pLinesToParse[1];
            
            tPlaylistEntry = super.parsePlaylistItem(pReferenceDirectory, pReadFromId3Tags, tAudioFilePath);
            fillMetaDataFromExtInf(tPlaylistEntry, tExtInfMetaData);
            
        } else {
            tPlaylistEntry = super.parsePlaylistItem(pReferenceDirectory, pReadFromId3Tags, pLinesToParse);
        }
        return tPlaylistEntry;
    }
    
    
    private void fillMetaDataFromExtInf(PlaylistEntry pPlaylistEntry, String pExtInfMetaData) {
        
        String tArtistName = "";
        String tSongTitle = "";

        String tHeaderLessMetaData = 
            pExtInfMetaData.replaceFirst(EXTINF_PREFIX_REGEX, "");
        String[] tArtistAndSong = tHeaderLessMetaData.split(SPLIT_ARTIST_AND_SONG_REGEX);
        if (tArtistAndSong.length == 2) {
            tArtistName = tArtistAndSong[0];
            tSongTitle = tArtistAndSong[1];
        }
        if (tArtistName != null && tArtistName.length() > 0) {
            pPlaylistEntry.setArtistName(tArtistName);
        }
        if (tSongTitle != null && tSongTitle.length() > 0) {
            pPlaylistEntry.setSongTitle(tSongTitle);
        }    
    }
    

    
    
}
